#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "udp.h"
#include "cmd.h"
#include <mh/common.h>
#include <mh/probe.h>
#include "pthread.h"


/*
 * 发送花样的第一行，宽度和高度信息
 */
int pe_send_first_row(PMH_UDP pudp, ushort width, ushort height)
{
    int i = 0;
    int retry = 3;
    MODIFY modify = { 0 };
    int total_size = width * height + width;
    int offset = 0;
    uchar *buf = (uchar*)calloc(width, sizeof (uchar));

    modify.cmd = CMD_MODIFY_PAT;
    modify.total_size = total_size;
    /* 第一行 */
    buf[0] = width & 0x00FF;
    buf[1] = (width & 0xFF00) >> 8;
    buf[2] = height & 0x00FF;
    buf[3] = (height & 0xFF00) >> 8;

    while (i < width)
    {
        i += 1024;
        if(i < width)
        {
            modify.size = 1024;
            modify.offset = offset;
            modify.content = buf + offset;
            offset += 1024;
            retry = 3;
PAT_FR_RETRY1:
            if (cmd_modify(pudp, &modify) < 0)
            {
                retry--;

                if (retry < 0)
                {
                    goto PAT_FR_FAIL;
                }
                goto PAT_FR_RETRY1;
            }
        }
    }

    modify.size = width - offset;
    modify.content = buf + offset;
    modify.offset = offset;
    retry = 3;
PAT_FR_RETRY2:
    if (cmd_modify(pudp, &modify) < 0)
    {
        retry--;
        if (retry < 0)
        {
            return -1;
        }
        goto PAT_FR_RETRY2;
    }
PAT_FR_FAIL:
    free(buf);
    return 0;
}
/*
 * 发送花样给下位机,1次发10行
 */
int pe_send_file(PMH_UDP pudp, uchar *buf, ushort width, ushort height)
{
    int i = 0;
    int retry = 3;
    MODIFY modify = { 0 };
    int total_size = width * height + width;
    int pat_offset = 0;

    modify.cmd = CMD_MODIFY_PAT;
    modify.total_size = total_size;
    modify.offset = 0;


    /* 发送第一行 */
    if (pe_send_first_row(pudp, width, height) < 0)
    {
        return -1;
    }

    pat_offset = 0;
    while (i < total_size - width)
    {
        i += 1024;
        if(i < total_size - width)
        {
            modify.size = 1024;
            modify.offset = pat_offset + width;
            modify.content = buf + pat_offset;
            pat_offset += 1024;
            retry = 3;
PAT_RETRY1:
            if (cmd_modify(pudp, &modify) < 0)
            {
                retry--;

                if (retry < 0)
                {
                    return -1;
                }
                goto PAT_RETRY1;
            }
        }
    }

    modify.size = total_size - pat_offset - width;
    modify.content = buf + pat_offset;
    modify.offset = pat_offset + width;
    retry = 3;
PAT_FR_RETRY2:
    if (cmd_modify(pudp, &modify) < 0)
    {
        retry--;
        if (retry < 0)
        {
            return -1;
        }
        goto PAT_FR_RETRY2;
    }

    return 0;
}
/*
 * 发送程式给下位机,1次发10行
 */
int program_send_file(PMH_UDP pudp, KNIT_PAGE *con_buf, unsigned short line)
{
    int i = 0;
    int j = 0;
    int ret = 0;
    int retry = 3;
    MODIFY modify = { 0 };
    int total_size = (line + 1) * sizeof(KNIT_PAGE);//one line for head
    int size = 10 * sizeof(KNIT_PAGE);
    int n = line / 10;
    int m = line - n * 10 + 1;
    int times = 0;
    uchar *buf = (uchar*)calloc(10, sizeof(KNIT_PAGE));

    modify.cmd = CMD_MODIFY_CNT;
    modify.total_size = total_size;
    for (i = 0; i < n + 1; i++)
    {
        times = (i < n) ? 10 : m;
        retry = 3;
        modify.offset = i * size;
        modify.size = times * sizeof(KNIT_PAGE);
        modify.content = buf;

        for (j = 0; j < times; j++)
        {
            uchar *pdes = buf + j * sizeof(KNIT_PAGE);
            uchar *psrc = (uchar*)&con_buf[i * 10 + j];
            memcpy((void*)pdes, (void*)psrc, sizeof(KNIT_PAGE));
        }

CNT_RETRY:
        if (cmd_modify(pudp, &modify) < 0)
        {
            retry--;

            if (retry < 0)
            {
                ret = -1;
                goto CNT_FAIL;
            }
            goto CNT_RETRY;
        }
    }
CNT_FAIL:
    free(buf);
    if(ret)
    {
        printf("failed to send program\n");
    }
    return ret;
}
/*
 * send speed data
 */
int speed_send_file(PMH_UDP pudp, PMH_SPEED speed_array, pthread_mutex_t *pudp_mutex)
{
    int ret = 0;
    int retry = 3;
    MODIFY modify = { 0 };
    int total_size = sizeof (MH_SPEED);
    int size = total_size;

    modify.cmd = CMD_MODIFY_SPEED;
    modify.total_size = total_size;
    modify.size = size;
    modify.offset = 0;
    modify.content = (uchar*)speed_array;
SPEED_RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);
    if (ret < 0)
    {
        retry--;

        if (retry < 0)
        {
            return -1;
        }
        goto SPEED_RETRY;
    }

    printf("send speed file success\n");
    return 0;
}
/*
 *
 */
int dumu_send_file(PMH_UDP pudp, PMH_DUMU dumu_array, pthread_mutex_t *pudp_mutex)
{
    int ret = 0;
    int retry = 3;
    MODIFY modify = { 0 };
//    pthread_mutex_init(pudp_mutex, NULL);
    modify.cmd = CMD_MODIFY_STITCH;
    modify.total_size = sizeof(MH_DUMU);
    modify.size = modify.total_size;
    modify.offset = 0;
    modify.content = (uchar*)dumu_array;
DUMU_RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);
    if (ret < 0)
    {
        retry--;

        if (retry < 0)
        {
            return -1;
        }
        goto DUMU_RETRY;
    }

    printf("send dumu file success\n");
    return 0;
}
/*
 * send yarn before data
 */
int yarn_before_send_file(PMH_UDP pudp, PYARN_BEFORE_NEEDLE pyarn_before_needle)
{
    int retry = 3;
    MODIFY modify = { 0 };
    int total_size = sizeof (YARN_BEFORE_NEEDLE);
    int size = total_size;

    modify.cmd = CMD_MODIFY_YARNBEFOR;
    modify.total_size = total_size;
    modify.size = size;
    modify.offset = 0;
    modify.content = (uchar*)pyarn_before_needle;

YARNBEFORE_RETRY:
    if (cmd_modify(pudp, &modify) < 0)
    {
        retry--;

        if (retry < 0)
        {
            return -1;
        }
        goto YARNBEFORE_RETRY;
    }

    printf("send yarnbefore file success\n");
    return 0;
}
/*
 * send yarn stoped data 沙嘴停放点
 */
int yarn_stop_send_file(PMH_UDP pudp, PYARN_STOP yarn_stop)
{
    int retry = 3;
    MODIFY modify = { 0 };
    int total_size = sizeof (YARN_STOP);
    int size = total_size;

    modify.cmd = CMD_MODIFY_YCPARKPOS;
    modify.total_size = total_size;
    modify.size = size;
    modify.offset = 0;
    modify.content = (uchar*)yarn_stop;
YARNSTOP_RETRY:
    if (cmd_modify(pudp, &modify) < 0)
    {
        retry--;

        if (retry < 0)
        {
            return -1;
        }
        goto YARNSTOP_RETRY;
    }

    printf("send yarnstop file success\n");
    return 0;
}
/*
 * send yarn exchanged data
 */
int yarn_exchange_send_file(PMH_UDP pudp, PYARN_EXCHANGE yarn_exchange, pthread_mutex_t *pudp_mutex)
{
    int retry = 3;
    int ret = 0;
    MODIFY modify = { 0 };
    int total_size = sizeof(YARN_EXCHANGE);
    int size = total_size;
    modify.cmd = CMD_MODIFY_CHANGEYARN;
    modify.total_size = total_size;
    modify.size = size;
    modify.offset = 0;
    modify.content = (uchar*)yarn_exchange;
YARNCHNG_RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);

    if (ret < 0)
    {
        retry--;

        if (retry < 0)
        {
            return -1;
        }
        goto YARNCHNG_RETRY;
    }

    printf("send yarnchng file success\n");
    return 0;
}
/*
 * send ext piece data
 */
int extpiece_send_file(PMH_UDP pudp, PEXT_PIECE extpiece, pthread_mutex_t *pudp_mutex)
{
    int retry = 3;
    MODIFY modify = { 0 };
    int ret = 0;

    int total_size = sizeof (EXT_PIECE);
    int size = total_size;

    modify.cmd = CMD_MODIFY_MULTICLOTH;
    modify.total_size = total_size;
    modify.size = size;
    modify.offset = 0;
    modify.content = (uchar*)extpiece;

EXTPIECE_RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);

    if (ret < 0)
    {
        retry--;

        if (retry < 0)
        {
            return -1;
        }
        goto EXTPIECE_RETRY;
    }

    printf("send extpiece file success\n");
    return 0;
}
/*
 * 发送系统参数给下位机
 */
int sysprm_send_file(PMH_UDP pudp, PSYS_PARAM psys_param)
{
    int retry = 3;

    MODIFY modify;
    modify.cmd = CMD_MODIFY_SYSPRM;
    modify.offset = 0;
    modify.total_size = sizeof(SYS_PARAM);
    modify.size = modify.total_size;
    modify.content = (uchar*)psys_param;

RETRY:
    if (cmd_modify(pudp, &modify) < 0)
    {
        retry--;
        if (retry < 0)
        {
            return -1;
        }
        goto RETRY;
    }

    return 0;
}
/*
 * 发送工作参数给下位机
 */
int workprm_send_file(PMH_UDP pudp, PWORK_PARAM pwork_param)
{
    int retry = 3;

    MODIFY modify;
    modify.offset = 0;
    modify.cmd = CMD_MODIFY_WORKPRM;
    modify.total_size = sizeof (WORK_PARAM);
    modify.size = modify.total_size;
    modify.content = (uchar*)pwork_param;
RETRY:
    if (cmd_modify(pudp, &modify) < 0)
    {
        retry--;
        if (retry < 0)
        {
            return -1;
        }
        goto RETRY;
    }

    return 0;
}
/*
 * 发送隐藏工作参数给下位机
 */
int hideprm_send_file(PMH_UDP pudp, PHIDE_PARAM phide_param)
{
    int retry = 3;

    MODIFY modify;
    modify.offset = 0;
    modify.cmd = CMD_MODIFY_HIDEPRM;
    modify.total_size = sizeof (HIDE_PARAM);
    modify.size = modify.total_size;
    modify.content = (uchar*)phide_param;
RETRY:
    if (cmd_modify(pudp, &modify) < 0)
    {
        retry--;
        if (retry < 0)
        {
            return -1;
        }
        goto RETRY;
    }

    return 0;
}
/*
 * 发送机器参数给下位机
 */
int macparam_send_file(PMH_UDP pudp, PMAC_PARAM pmac_param)
{
    int retry = 3;
    MODIFY modify;
    modify.offset = 0;
    modify.cmd = CMD_MODIFY_MACPARAM;
    modify.total_size = sizeof (MAC_PARAM);
    modify.size = modify.total_size;
    modify.content = (uchar*)pmac_param;
RETRY:
    if (cmd_modify(pudp, &modify) < 0)
    {
        retry--;
        if (retry < 0)
        {
            return -1;
        }
        goto RETRY;
    }

    return 0;
}
/*
 * 发送摇床参数给下位机
 */
int rock_send_file(PMH_UDP pudp, PROCK_POS prock_pos, pthread_mutex_t *pudp_mutex)
{
    int retry = 3;
    int ret = 0;

    MODIFY modify;
    modify.offset = 0;
    modify.cmd = CMD_MODIFY_ROCK;
    modify.total_size = sizeof (ROCK_POS);
    modify.size = modify.total_size;
    modify.content = (uchar*)prock_pos;
RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);

    if (ret < 0)
    {
        retry--;
        if (retry < 0)
        {
            return -1;
        }
        goto RETRY;
    }

    return 0;
}
/*
 * send cloth num
 */
int clothnum_send_file(PMH_UDP pudp, PCLOTH_NUM pcloth_num, pthread_mutex_t *pudp_mutex)
{
    int retry = 2;
    int ret = 0;

    MODIFY modify = { 0 };
    modify.cmd = CMD_MODIFY_CLOTHNUM;
    modify.offset = 0;
    modify.content =  (uchar*)pcloth_num;
    modify.total_size = sizeof(CLOTH_NUM);
    modify.size = sizeof(CLOTH_NUM);

RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);

    if (ret < 0)
    {
        if (retry-- < 0)
        {
            return -1;
        }
        goto RETRY;
    }

    printf("send clothnum file success\n");
    return 0;
}
/*
 * send alarmmask file
 */
int alarmmask_send_file(PMH_UDP pudp, PALARM_MASK palarm, pthread_mutex_t *pudp_mutex)
{
    int retry = 2;
    int ret = 0;

    MODIFY modify;
    modify.offset = 0;
    modify.cmd = CMD_MODIFY_ALARMMASK;
    modify.total_size = sizeof(ALARM_MASK);
    modify.size = modify.total_size;
    modify.content = (uchar*)palarm;

RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);

    if (ret < 0)
    {
        if (retry-- < 0)
        {
            return -1;
        }
        goto RETRY;
    }

    return 0;
}
/*
 * send dumu amend data
 */
int dmbz_send_file(PMH_UDP pudp, PSTITCH_AMEND psa, pthread_mutex_t *pudp_mutex)
{
    int retry = 3;
    int ret = 0;
    MODIFY modify;
    modify.cmd = CMD_MODIFY_STITCHAMEND;
    modify.offset = 0;
    modify.total_size = sizeof (STITCH_AMEND);
    modify.size = modify.total_size;
    modify.content = (uchar*)psa;
RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);

    if (ret < 0)
    {
        if (retry-- < 0)
        {
            return -1;
        }
        goto RETRY;
    }

    return 0;
}

/*
 * send ext piece data
 */
int sink_send_file(PMH_UDP pudp, SINK_PIECE sinkdata, pthread_mutex_t *pudp_mutex)
{
    int retry = 3;
    MODIFY modify = { 0 };
    int ret = 0;

    int total_size = sizeof (SINK_DATA);
    int size = total_size;

    modify.cmd = CMD_MODIFY_SINK;
    modify.total_size = total_size;
    modify.size = size;
    modify.offset = 0;
    modify.content = (uchar*)sinkdata;

EXTPIECE_RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);

    if (ret < 0)
    {
        retry--;

        if (retry < 0)
        {
            return -1;
        }
        goto EXTPIECE_RETRY;
    }

    return 0;
}
/*
 * send ext piece data
 */
int cam_send_file(PMH_UDP pudp, CAM_PIECE camdata, pthread_mutex_t *pudp_mutex)
{
    int retry = 3;
    MODIFY modify = { 0 };
    int ret = 0;

    int total_size = sizeof (CAM_DATA);
    int size = total_size;
    modify.cmd = CMD_MODIFY_CAMSETTING;
    modify.total_size = total_size;
    modify.size = size;
    modify.offset = 0;
    modify.content = (uchar*)camdata;

EXTPIECE_RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);

    if (ret < 0)
    {
        retry--;

        if (retry < 0)
        {
            return -1;
        }
        goto EXTPIECE_RETRY;
    }

    return 0;
}
/*
 * send ext piece data
 */
int yarn_feed_send_file(PMH_UDP pudp, YARNFEEDER_PIECE yarndata, pthread_mutex_t *pudp_mutex)
{
    int retry = 3;
    MODIFY modify = { 0 };
    int ret = 0;

    int total_size = sizeof (YARNFEEDER_DATA);
    int size = total_size;

    modify.cmd = CMD_MODIFY_YARNFEEDER;
    modify.total_size = total_size;
    modify.size = size;
    modify.offset = 0;
    modify.content = (uchar*)yarndata;

EXTPIECE_RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);

    if (ret < 0)
    {
        retry--;

        if (retry < 0)
        {
            return -1;
        }
        goto EXTPIECE_RETRY;
    }

    return 0;
}

/*
 * send board param
 */
int board_param_send_file(PMH_UDP pudp, PBOARD_PARAM boarddata, pthread_mutex_t *pudp_mutex)
{
    int retry = 3;
    MODIFY modify = { 0 };
    int ret = 0;

    int total_size = sizeof (BOARD_PARAM);
    int size = total_size;

    modify.cmd = CMD_MODIFY_COMBPARAM;
    modify.total_size = total_size;
    modify.size = size;
    modify.offset = 0;
    modify.content = (uchar*)boarddata;

EXTPIECE_RETRY:
    pthread_mutex_lock(pudp_mutex);
    ret = cmd_modify(pudp, &modify);
    pthread_mutex_unlock(pudp_mutex);

    if (ret < 0)
    {
        retry--;

        if (retry < 0)
        {
            return -1;
        }
        goto EXTPIECE_RETRY;
    }

    return 0;
}

/*
 * send jijia upgrade
 */

int jijia_upgrade_send_file(PMH_UDP pudp, uchar *data, int file_size, pthread_mutex_t *pudp_mutex)
{
    MODIFY modify = { 0 };
    int total_size = file_size;
    int retry =2;
    int ret = 0;
    int count_la = 0;
    int n = 0;
    int send_count = total_size/1024;
    count_la = total_size - send_count*1024;

    total_size = send_count *1024 + (count_la > 0 ?1024 : 0);

    modify.cmd = CMD_MODIFY_JIJIA;
    modify.total_size = total_size;
    modify.offset = 0;
    modify.size = 1024;
    modify.content = (uchar*)data;
    while(send_count)
    {
        send_count--;
        modify.offset = n*1024;
        modify.content = (uchar*)&data[n*1024];

        n++;
SPEED_RETRY:
         pthread_mutex_lock(pudp_mutex);
        ret = cmd_modify(pudp, &modify);
        pthread_mutex_unlock(pudp_mutex);
        ret = 0;
        if (ret < 0)
        {
            retry--;

            if (retry < 0)
            {
                return -1;
            }
            goto SPEED_RETRY;
        }
    }
    if(count_la !=0 )
    {
        char buf_fle[1024] ;
        memset(buf_fle, 0xff, 1024);
        modify.offset = n*1024;
        memcpy(buf_fle, &data[n*1024], count_la);
        modify.content = (uchar*)buf_fle;
        modify.size = 1024;
        int m = 0;
        while(m<1024)
        {

            m =m + 8;
        }
        pthread_mutex_lock(pudp_mutex);
        ret = cmd_modify(pudp, &modify);
        pthread_mutex_unlock(pudp_mutex);
        ret = 0;
        if (ret < 0)
        {
            retry--;

            if (retry < 0)
            {
                return -1;
            }
            goto SPEED_RETRY;
        }
    }
    return 0;
}

